// hosts
package main

import (
	"bufio"

	"net"
	"os"

	"regexp"
	"strings"

	"github.com/miekg/dns"
)

/**
 * 自定义hosts的操作类
 */
type Hosts struct {
	file     string
	hosts    map[string]string
	filetime int64
}

const DOT = "."

/**
 * 获取域名的泛字符串，即qq.com. => *.qq.com.
 */
func (h *Hosts) _getWildcardDomain(domain string) string {
	domain = dns.Fqdn(domain)
	spl := strings.Split(domain, DOT)
	var render string
	if len(spl) < 4 {
		render = domain
	} else {
		spl[0] = "*"
		render = strings.Join(spl, DOT)
	}
	return render
}

/**
 *获取自定义域名指定的ip
 */
func (h *Hosts) getSelfIp(domain string) string {
	wdomain := h._getWildcardDomain(domain)
	if h._getIp(domain) != "" {
		return h._getIp(domain)
	} else if h._getIp(wdomain) != "" {
		return h._getIp(wdomain)
	}
	return ""
}
func (h *Hosts) _getIp(domain string) string {
	var render string
	for k, v := range h.hosts {
		if domain == k {
			render = v
			break
		}
	}
	return render
}

/**
 * 设置文件地址
 */
func (h *Hosts) setFile(filepath string) {
	h.file = filepath
}

/**
 * 加载自定义的host
 */
func (h *Hosts) referer() {
	buf, err := os.Open(h.file)
	if err != nil {
		panic("Can't open " + err.Error() + h.file)
	}
	defer buf.Close()

	file_stat, err := buf.Stat()
	if err != nil {
		panic("Can't get file stat " + err.Error() + h.file)
	}
	h.filetime = file_stat.ModTime().Unix()

	L("referer host config file")
	scanner := bufio.NewScanner(buf)
	for k, _ := range h.hosts {
		delete(h.hosts, k)
	}
	for scanner.Scan() {

		line := scanner.Text()
		line = strings.TrimSpace(line)

		if strings.HasPrefix(line, "#") || line == "" {
			continue
		}

		sli := strings.Split(line, " ")
		if len(sli) == 1 {
			sli = strings.Split(line, "\t")
		}

		if len(sli) < 2 {
			continue
		}

		domain := sli[len(sli)-1]
		ip := sli[0]
		if !h.isDomain(domain) || !h.isIP(ip) {
			continue
		}
		domain = dns.Fqdn(domain)
		h.hosts[domain] = ip
	}
}
func (h *Hosts) isDomain(domain string) bool {
	if h.isIP(domain) {
		return false
	}

	match, _ := regexp.MatchString("^[a-zA-Z0-9\\*][a-zA-Z0-9-\\.]+", domain)
	return match
}
func (h *Hosts) isIP(ip string) bool {
	return (net.ParseIP(ip) != nil)
}

func (h *Hosts) checkModify() bool {

	file, err := os.Open(h.file)
	if err != nil {
		panic("Can't open " + err.Error() + h.file)
	}
	file_stat, err := file.Stat()
	if err != nil {
		panic("Can't get file stat " + err.Error() + h.file)
	}
	file_time := file_stat.ModTime().Unix()
	file.Close()
	render := false
	if h.filetime != file_time {
		render = true
	}
	return render
}

func init() {
}
